#region Copyright (C) 2005-2006 Team MediaPortal

/* 
 *	Copyright (C) 2005-2006 Team MediaPortal
 *	http://www.team-mediaportal.com
 *
 *  This Program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *   
 *  This Program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *   
 *  You should have received a copy of the GNU General Public License
 *  along with GNU Make; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
 *  http://www.gnu.org/copyleft/gpl.html
 *
 */

#endregion

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Xml.Serialization;
using System.IO;
using System.Configuration;
using MediaPortal.GUI.Library;
using MediaPortal.Player;

namespace ProcessPlugins.WMPOSD
{
    public class OSDProgress : Form
    {
        #region Fields
        Bitmap _indicator;
        Bitmap _mid;
        Bitmap _background;
        Bitmap _top;
        Bitmap _bitmap;
        Timer _timer = new Timer();
        Form _parent;
        LinearGradientBrush _brushBottom;
        LinearGradientBrush _brushTop;
        LinearGradientBrush _brushPosBottom;
        LinearGradientBrush _brushPosTop;
        EventHandler _losc;
        readonly GraphicsPath _graphicsPath;
        #endregion

        #region Public methods

        public OSDProgress(Form parent)
        {
            this.SuspendLayout();

            this.AutoScaleDimensions = new System.Drawing.SizeF(16F, 31F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.AutoValidate = System.Windows.Forms.AutoValidate.Disable;
            this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(141)))), ((int)(((byte)(167)))), ((int)(((byte)(205)))));
            this.ClientSize = new System.Drawing.Size(286, 110);
            this.ControlBox = false;
            this.Font = new System.Drawing.Font("Microsoft Sans Serif", 20F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
            this.ForeColor = System.Drawing.Color.White;
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
            this.Margin = new System.Windows.Forms.Padding(8);
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "WMPOSD";
            this.ShowIcon = false;
            this.ShowInTaskbar = false;
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
            this.Text = "OSD";
            this.TopMost = true;

            this.ResumeLayout();

            //TODO: MediaPortal closes when WMP9OSD file is not found, why? 
            ConfigXmlDocument cxd = new ConfigXmlDocument();
            cxd.Load(GUIGraphicsContext.Skin + @"\WMPOSD.xml");
            _top = new Bitmap(GUIGraphicsContext.Skin + @"\Media\" + cxd.GetElementsByTagName("TopBackground")[0].InnerText);
            _mid = new Bitmap(GUIGraphicsContext.Skin + @"\Media\" + cxd.GetElementsByTagName("ProgressMid")[0].InnerText);
            _indicator = new Bitmap(GUIGraphicsContext.Skin + @"\Media\" + cxd.GetElementsByTagName("ProgressIndicator")[0].InnerText);
            _background = new Bitmap(GUIGraphicsContext.Skin + @"\Media\" + cxd.GetElementsByTagName("ProgressBackground")[0].InnerText);
            _bitmap = new Bitmap(1246, 65);
            try
            {
                DotNetGear.Drawing.PathFinder pf = new DotNetGear.Drawing.PathFinder(_top);
                _graphicsPath = pf.GetPath(_top.GetPixel(0,0));//Pixel 0,0 is transparent color.
            }
            catch (Exception ex)
            {
                Log.Error(ex);
            }
            _losc = new EventHandler(Parent_LocationOrSizeChanged);
            _parent = parent;
            this.Opacity = 0;
            this.SetStyle(ControlStyles.Selectable, false);
            base.Show(parent);
            Parent_LocationOrSizeChanged(null, null);
            _parent.LocationChanged += _losc;
            _parent.SizeChanged += _losc;
            _timer.Tick += new EventHandler(Timer_Tick);
            
            _brushBottom = new LinearGradientBrush(new Rectangle(0, 0, 10, _bitmap.Height / 2), Color.FromArgb(7, 142, 2), Color.FromArgb(14, 180, 11), LinearGradientMode.Vertical);
            _brushTop = new LinearGradientBrush(new Rectangle(0, _bitmap.Height / 2 - 1, 1, _bitmap.Height), Color.FromArgb(128, 196, 128), Color.FromArgb(61, 164, 57), LinearGradientMode.Vertical);
            _brushPosBottom = new LinearGradientBrush(new Rectangle(0, 0, 10, _bitmap.Height / 2), Color.Yellow, Color.DarkOrange, LinearGradientMode.Vertical);
            _brushPosTop = new LinearGradientBrush(new Rectangle(0, _bitmap.Height / 2 - 1, 1, _bitmap.Height), Color.LightYellow, Color.Yellow, LinearGradientMode.Vertical);
            parent.Focus();
        }

        public void Show(double d, double p, double m, string info, int delay)
        {              
            using (Graphics g = Graphics.FromImage(_bitmap))
            {
                try
                {
                    _timer.Enabled = false;
                    _timer.Interval = delay;
                    _timer.Enabled = true;
                    if (d == 0.0) d = double.MaxValue;
                    g.FillRectangle(new System.Drawing.Drawing2D.LinearGradientBrush(new Point(0, 0), new Point(0, _bitmap.Height), Color.White, Color.Black), 0, 0, _bitmap.Width, _bitmap.Height);
                    g.DrawImage(_top, 0, 0, _bitmap.Width, _bitmap.Height);
                    int x = (int)(_bitmap.Width * 0.11);
                    int y = (int)(_bitmap.Height * 0.25);
                    int h = (int)(_bitmap.Height * 0.5);
                    int w = (int)(_bitmap.Width * 0.65);
                    int wm = (int)((m / d) * (_bitmap.Width * 0.65));
                    int wp = (int)((p / d) * (_bitmap.Width * 0.65));
                    int iw = (int)(_indicator.Width / (_indicator.Height / (_bitmap.Height * 0.5)));
                    g.DrawImage(_background, x, y, w, h);
                    g.DrawImage(_mid, x, y, wm, h);
                    g.DrawImage(_indicator, x + wp - iw / 2, y, iw, h);
                    //TODO: Add colors, size and position to config !!!
                    g.DrawString(new TimeSpan(0, 0, (int)p).ToString(), this.Font, new SolidBrush(Color.White), 15, y);
                    if (d < double.MaxValue)
                    {
                        g.DrawString(new TimeSpan(0, 0, (int)d).ToString(), this.Font, new SolidBrush(Color.White), 960, y);
                    }
                    else
                    {
                        g.DrawString("STREAM", this.Font, new SolidBrush(Color.White), 960, y);//TODO: Think about text;
                    }
                    g.DrawString(info, this.Font, new SolidBrush(Color.Black), 1100, y);
                    this.Opacity = 1;
                    this.Refresh();
                }
                catch (Exception ex)
                {
                    Log.Error(ex);
                }
            }
        }

        #endregion

        #region Protected methods
        protected void Parent_LocationOrSizeChanged(object sender, EventArgs e)
        {
            try
            {
                double w = 0.90, h = 0.075, yp = 56;//TODO: Move to config file.
                this.Location = new Point((int)(_parent.Location.X + _parent.Size.Width * (1.0 - w) / 2), (int)(_parent.Location.Y + yp));
                this.Size = new Size((int)(_parent.Size.Width * w), (int)(_parent.Size.Height * h));
                if (_graphicsPath != null)
                {
                    GraphicsPath gp = new GraphicsPath();
                    gp.AddPolygon(_graphicsPath.PathPoints);
                    Matrix m = new Matrix();
                    m.Scale(this.Size.Width / (float)_top.Width, this.Size.Height / (float)_top.Height);
                    gp.Transform(m);
                    this.Region = new Region(gp);
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex);
            }
        }

        protected void Timer_Tick(object sender, EventArgs e)
        {
            try
            {
                this.Opacity = 0;
                this.Refresh();
            }
            catch (Exception ex)
            {
                Log.Error(ex);
            }
        }

        protected override void Dispose(bool disposing)
        {
            try
            {
                _parent.LocationChanged -= _losc;
                _parent.SizeChanged -= _losc;
                _timer.Dispose();
                if (_indicator != null) _indicator.Dispose();
                if (_mid != null) _mid.Dispose();
                if (_background != null) _background.Dispose();
                if (_top != null) _top.Dispose();
                if (_bitmap != null) _bitmap.Dispose();
                base.Dispose(disposing);
            }
            catch (Exception ex)
            {
                Log.Error(ex);
            }
        }       

        protected override void OnPaint(PaintEventArgs e)
        {
            try
            {
                e.Graphics.DrawImage(_bitmap, new Rectangle(0, 0, this.Width, this.Height));
            }
            catch (Exception ex)
            {
                Log.Error(ex);
            }
        }
        #endregion
    }
}